/*
 *	create by senllang 2023/5/3
 *  mail : study@senllang.onaliyun.com
 *	
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
#include <string.h>
#include "ipc_mutex.h"


/*
 * 创建共享互斥量
 *
 * create by senllang 2023/5/2
 *
 * pMemAddr, 共享内存地址
 * Num， 互斥量数量，地址为连续存放
 */
int InitMutex(char *pMemAddr, int Num)
{
	pthread_mutex_t *pMutex = NULL;
	pthread_mutexattr_t mutexAttr;
	int i = 0;
	
	if((NULL == pMemAddr) || (Num == 0))
	{
		printf("Invalid args \n");
		return -1;
	}
	
	if(0 != pthread_mutexattr_init(&mutexAttr))
	{
	    printf("mutex attr init err [%s]\n",strerror(errno));
        return -1;
    }
	
	if(0 != pthread_mutexattr_setpshared(&mutexAttr, PTHREAD_PROCESS_SHARED))
	{
        printf("mutex attr setshare err[%s]\n",strerror(errno));
        return -1;
    }
	
	if(0 != pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_ERRORCHECK))
	{
        printf("mutex attr settype err[%s]\n",strerror(errno));
        return -1;
    }

	pMutex = (pthread_mutex_t*)pMemAddr;
	for(i = 0; i < Num; i++)
	{
		if(0 != pthread_mutex_init(&pMutex[i], &mutexAttr))
		{
			printf("mutex init err[%s]\n",strerror(errno));
			return -1;
		}	
	}
	
	pthread_mutexattr_destroy(&mutexAttr);
	
	return 0;
}

/*
 * 共享互斥量加锁
 *
 * create by senllang 2023/5/2
 *
 * pMemAddr, 共享内存地址
 */
void MutexLock(char *pMemAddr)
{
	pthread_mutex_t *pMutex = (pthread_mutex_t*)pMemAddr;
	pthread_mutex_lock(pMutex);
}

/*
 * 解锁共享互斥量
 *
 * create by senllang 2023/5/2
 *
 * pMemAddr, 共享内存地址
 */
void MutexUnlock(char *pMemAddr)
{
	pthread_mutex_t *pMutex = (pthread_mutex_t*)pMemAddr;
	pthread_mutex_unlock(pMutex);
}

/*
 * 销毁共享互斥量
 *
 * create by senllang 2023/5/2
 *
 * pMemAddr, 共享内存地址
 * Num， 互斥量数量，地址为连续存放
 */
void DestroyMutex(char *pMemAddr, int Num)
{
	pthread_mutex_t *pMutex = (pthread_mutex_t*)pMemAddr;
	
	for(int i = 0; i < Num; i++)
		pthread_mutex_destroy(&pMutex[i]);
}

/*
 * 获取互斥量内存大小
 *
 * create by senllang 2023/5/2
 *
 * Num， 互斥量数量，地址为连续存放
 */
int GetMutexSize(int Num)
{
	return sizeof(pthread_mutex_t)*Num;
}
